#include "StageSketcher.h"
#include "Resolution.h"
#include "Source.h"

#define TOP_MARGIN 7
#define MARGIN 1.1

StageSketcher::StageSketcher(void){
}

StageSketcher::StageSketcher(Stage * stage){
        this->stage = stage;
}

StageSketcher::~StageSketcher(void){
}

void StageSketcher::draw(void){
Uint32 initialTick = SDL_GetTicks();
        // Pinta el escenario.
        Texture * stageTexture = stage->getTexture();
        Color * stageLineColor = stage->getLineColor();
        Color * stageBackgroundColor = stage->getElementColor();
        Resolution * resolution = stage->getResolution();
        if(stageTexture != NULL) {
                SketcherHelper::getInstance()->initializeInstance(resolution->getWidth(),resolution->getHeight(),stageTexture,stageLineColor);
        }else {
                SketcherHelper::getInstance()->initializeInstance(resolution->getWidth(),resolution->getHeight(),stageBackgroundColor,stageLineColor);
        }
        int margin = MARGIN*resolution->getWidth()/100;
        int topMargin = TOP_MARGIN*resolution->getHeight()/100;
        
        stage->setDrawableArea(new Resolution(resolution->getWidth()-2*margin,resolution->getHeight()-(margin+topMargin) ));
        // Pinta los elementos:

        float minPosX=1000000;
        float minPosY=1000000;
        float maxPosY=-1000000;
        float maxPosX=-1000000;
        Rail* rail=this->stage->getRail();
        Frog* frog= this->stage->getFrog();
        Drainage* drainage = this->stage->getDrainage();
        this->stage->setActiveBall(NULL);
        Source* source= this->stage->getSource();
        /*Checking positions for Rail*/

        if(rail->getMinXPos()<minPosX)minPosX=rail->getMinXPos();
        if(rail->getMaxXPos()>maxPosX)maxPosX=rail->getMaxXPos();
        if(rail->getMinYPos()<minPosY)minPosY=rail->getMinYPos();
        if(rail->getMaxYPos()>maxPosY)maxPosY=rail->getMaxYPos();
        /*Checking positions for frog*/
        if(frog->getMinXPos()<minPosX)minPosX=frog->getMinXPos();
        if(frog->getMaxXPos()>maxPosX)maxPosX=frog->getMaxXPos();
        if(frog->getMinYPos()<minPosY)minPosY=frog->getMinYPos();
        if(frog->getMaxYPos()>maxPosY)maxPosY=frog->getMaxYPos();
        /*Checking positions for Drainage*/
        if(drainage->getMinXPos()<minPosX)minPosX=drainage->getMinXPos();
        if(drainage->getMaxXPos()>maxPosX)maxPosX=drainage->getMaxXPos();
        if(drainage->getMinYPos()<minPosY)minPosY=drainage->getMinYPos();
        if(drainage->getMaxYPos()>maxPosY)maxPosY=drainage->getMaxYPos();


        /*Checking positions for Sources*/
        /*
        if(source->getMinXPos()<minPosX)minPosX=source->getMinXPos();
        if(source->getMaxXPos()>maxPosX)maxPosX=source->getMaxXPos();
        if(source->getMinYPos()<minPosY)minPosY=source->getMinYPos();
        if(source->getMaxYPos()>maxPosY)maxPosY=source->getMaxYPos();           
*/
        list<DrawableElement*> * obstacles = stage->getObstacles();
        list<DrawableElement*>::iterator iterObstacles;
        for(iterObstacles = obstacles->begin(); iterObstacles != obstacles->end(); iterObstacles++) {
                DrawableElement * obstacle = (*iterObstacles);
                if(obstacle->getMinXPos()<minPosX)minPosX=obstacle->getMinXPos();
                if(obstacle->getMaxXPos()>maxPosX)maxPosX=obstacle->getMaxXPos();
                if(obstacle->getMinYPos()<minPosY)minPosY=obstacle->getMinYPos();
                if(obstacle->getMaxYPos()>maxPosY)maxPosY=obstacle->getMaxYPos();
        }
        float positionWidth=maxPosX-minPosX;
        float positionHeight=maxPosY-minPosY;

        float coeficienteX = stage->getDrawableArea()->getWidth()/positionWidth;
        float coeficienteY = stage->getDrawableArea()->getHeight()/positionHeight;
        float coeficiente;

        int initialX;
        int initialY;

        if(coeficienteX<coeficienteY){
                coeficiente=coeficienteX;
                initialX = minPosX*coeficiente;
                initialY = minPosY*coeficiente;
                initialY = initialY+ (stage->getDrawableArea()->getHeight()-positionHeight*coeficiente)/2;
        }else{
                coeficiente=coeficienteY;
                initialX = minPosX*coeficiente;
                initialY = minPosY*coeficiente;
                initialX = initialX- (stage->getDrawableArea()->getWidth()-positionWidth*coeficiente)/2;
        }
        initialX = initialX - margin;
        initialY = initialY + topMargin;
        
        int pixelsHeight = positionHeight*coeficiente;

        SketcherHelper::getInstance()->setCoefs(coeficienteX, coeficienteY, coeficiente, initialX, initialY, pixelsHeight);
		Uint32 endTick = SDL_GetTicks();
		cout << "PreDraw took " << endTick - initialTick << endl;
        /*Drawing Rail*/
        rail->setHeight(rail->getHeight()*coeficiente);
        for(list<Position*> ::iterator point = rail->getPoints()->begin();point != rail->getPoints()->end(); point++){
                Position *position = SketcherHelper::getInstance()->getPositionInPixels(*point);
                (*point)->setPixel(position->getPixelX(),position->getPixelY());
        }
		stage->setVelocity(stage->getVelocity()->getModule());

        rail->draw();

        /*Drawing Frog*/
        Position* position = SketcherHelper::getInstance()->getPositionInPixels(frog->getPosition());
        frog->setRadius(frog->getRadius()*coeficiente);
        frog->getPosition()->setPixel(position->getPixelX(),position->getPixelY());
        frog->draw();


        /*Drawing Drainage*/
        position = SketcherHelper::getInstance()->getPositionInPixels(drainage->getPosition());
        drainage->setRadius(drainage->getRadius()*coeficiente);
        drainage->getPosition()->setPixel(position->getPixelX(),position->getPixelY());
        drainage->draw();

        /*Drawing Sources*/
        position = SketcherHelper::getInstance()->getPositionInPixels(source->getPosition());
        source->setRadius(source->getRadius()*coeficiente);
        source->getPosition()->setPixel(position->getPixelX(),position->getPixelY());
        source->draw();
	
        for(iterObstacles = obstacles->begin(); iterObstacles != obstacles->end(); iterObstacles++) {
                DrawableElement * obstacle = *iterObstacles;
                position = SketcherHelper::getInstance()->getPositionInPixels(obstacle->getPosition());
                obstacle->setPosition(position);
                obstacle->draw();
        }
		
		SketcherHelper::getInstance()->endInitialicing();
}